package com.koomii.common.dubbo.filter;

import org.apache.log4j.Logger;

import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.RpcResult;
import com.koomii.common.dubbo.bean.AuthToken;

/**
 * dubbo服务权限拦截
 * @author lizongyue
 *
 */
@Activate(group={"provider"})
public class AuthFilter implements Filter {
    private static Logger log = Logger.getLogger(AuthFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        log.debug("-----------------START----------------------------");
        log.debug("====invoker interface name:"+invoker.getInterface().getName());
        log.debug("====invoker class name:"+invoker.getClass().getName());
        log.debug("====invoker url:"+invoker.getUrl());
        log.debug("====invocation method name:"+invocation.getMethodName());
        Object[] args = invocation.getArguments();
        for(int i=0;i<args.length;i++){
            log.debug("====invocation arg-"+i+":"+args[i]);
        }
        int index = getAuthTokenIndex(invocation);
        if(index >= 0){//有AuthToken对象，需要鉴权
            try {
                Class[] pts = invocation.getParameterTypes();
                String key = pts[index].getMethod("getKey").invoke(args[index]).toString();
                if(AuthToken.TEST_KEY.equals(key)){
                    log.debug("-=-鉴权=====KEY正确====继续执行==");
                }else{
                    log.error("====鉴权====KEY错误===不再执行====");
                    return new RpcResult(new RpcException("key is error,refuse request"));
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
            }
        }else{//没有AuthToken对象，不需要鉴权
            log.debug("==---不需要鉴权========---");
        }
        log.debug("====invocation getAttachments keys:"+invocation.getAttachments().keySet());
        log.debug("====invocation getAttachments values:"+invocation.getAttachments().values());
        log.debug("-----------------END---------------------------");
        return invoker.invoke(invocation);
    }
    
    /**
     * 获取AuthToken对象在参数中的位置
     * @param invocation
     * @return -1：没有AuthToken，>=0 则表示AuthToken在arg是中的位置
     */
    private int getAuthTokenIndex(Invocation invocation){
        Class[] pts = invocation.getParameterTypes();
        for(int i=0;i<pts.length;i++){
            log.debug("====invocation ParameterType-"+i+":"+pts[i].getName());
            if(pts[i].getName() == "com.koomii.common.dubbo.bean.AuthToken"){
                return i;
            }
        }
        return -1;
    }
    
}
